<template>

  <div class="container">
    <div class="card1">
      <div class="title">二维码生成设置</div>
      <div class="lcontainer">
        <div style="flex:0 0 200px;display: flex;align-items: center;">
          <div style="font-size: 12px;width: 60px;">生成内容</div>
          <textarea placeholder="请输入二维码内容" rows="4" id="qrInfo" v-model="qrInfo"
            style="flex: 1 1 140px;background: #F2F3F5;border: none;font-size: 12px;margin-bottom: 15px;padding: 10px;"></textarea>
          <br />
        </div>
        <div style="display: flex;">
          <div style="flex:0 0 200px;display: flex;align-items: center;">
            <div style="font-size: 12px;width: 60px;">掩膜图形</div>
            <select v-model="selectedCover" id="qrCover"
              style="width: 140px;background: #F2F3F5;border: none;font-size: 12px;height: 28px;">
              <option value="000">0 0 0</option>
              <option value="001">0 0 1</option>
              <option value="010">0 1 0</option>
              <option value="011">0 1 1</option>
              <option value="100">1 0 0</option>
              <option value="101">1 0 1</option>
              <option value="110">1 1 0</option>
              <option value="111">1 1 1</option>
            </select>
          </div>
          <div style="display: flex;flex:1 1 420px;align-items: center;margin-left: 50px;">
            <div style="flex: 0 0 120px;">
              <MButton style="width: 120px;" @click="generateGrid">重置手绘区域</MButton>
            </div>
            <div style="flex: 1 1 550px;text-align: right;padding: 0 10px;">
              <MButton style="width: 100px;" @click="conflateCode">合成二维码</MButton>
              <MButton style="width: 100px;margin-left: 30px;" @click="downloadQRCode">下载二维码</MButton>
              <MButton style="width: 100px;margin-left: 30px;" @click="handleUploadClick">上传识别</MButton>
              <MInput style="width: 200px;margin-left: 10px;" v-model="identifyInfo"></MInput>
              <input type="file" @change="handleFileChange" accept="image/*" style="display: none" />
            </div>
          </div>
        </div>
      </div>
      <div style="margin-top: 30px;">
        <div style="margin-top: 20px;text-align: left;">预览</div>
        <div style="display: flex;margin-top: 10px;">
          <MButton style="width: 80px;margin-left: 30px;" @click="step1">矩阵</MButton>
          <MButton style="width: 80px;margin-left: 30px;" @click="step2">黑白块</MButton>
          <MButton style="width: 80px;margin-left: 30px;" @click="step3">格式信息</MButton>
          <MButton style="width: 80px;margin-left: 30px;" @click="step4">数据位</MButton>
          <MButton style="width: 80px;margin-left: 30px;" @click="step5">掩膜合并</MButton>
          <MButton style="width: 80px;margin-left: 30px;background: white;color: black;border: 1px solid #e2e2e2;"
            @click="step1">清除</MButton>

        </div>
      </div>
      <div style="margin-top: 30px;height: 510px;">
        <div class="title">二维码手绘</div>
        <div style="display: flex;">
          <div style="flex: 1 1 350px;display: flex;justify-content: right;">
            <table v-if="tableData1.length > 0">
              <tbody>
                <tr v-for="(row, rowIndex) in tableData1" :key="rowIndex">
                  <td v-for="(cell, colIndex) in row" :key="`${rowIndex}-${colIndex}`"
                    :style="{ backgroundColor: cell === 1 ? 'black' : 'white' }"></td>
                </tr>
              </tbody>
            </table>
          </div>
          <div style="flex: 1 1 350px;margin-left: 50px;">
            <table v-if="tableData.length > 0" ref="qrTable">
              <tbody>
                <tr v-for="(row, rowIndex) in tableData" :key="rowIndex">
                  <td v-for="(cell, colIndex) in row" :key="`${rowIndex}-${colIndex}`"
                    :style="{ backgroundColor: cell.color, border: isMake ? 'none' : '1px solid #dadada' }"
                    :class="cell.highlight ? 'highlight' : ''" @mouseover="highlightCell(rowIndex, colIndex)"
                    @mouseout="removeHighlight(rowIndex, colIndex)" @click="toggleCellColor(rowIndex, colIndex)"></td>
                </tr>
              </tbody>
            </table>
          </div>

        </div>
      </div>
      <div style="font-size: 12px;bottom: 5px;">
        *该工具仅支持数字，手绘二维码版本为1
      </div>
    </div>

  </div>
</template>

<script>
import MButton from '../components/MButton.vue'
import MInput from '../components/MInput.vue'
import { ref, onMounted } from 'vue';
import html2canvas from 'html2canvas';
import jsQR from 'jsqr';
export default {
  name: 'QrDestroy',
  props: {
    msg: String
  },
  components: {
    MButton,
    MInput
  },

  setup() {
    const selectedLevel = ref('3')
    const selectedVersion = ref('1')
    const selectedCover = ref("000")
    const numbers = ref(Array.from({ length: 4 }, (_, i) => i));
    const tableData = ref([]);
    const tableData1 = ref([]);
    const qrTable = ref(null);
    const valueList = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
    const qrInfo = ref("5201314")
    const isCreate = ref(false)
    const isDraw = ref(false)
    const identifyInfo = ref("")

    const info = [
      ["X", "X", "X", "X", "X", "X", "X", "O", "A0", "17-6", "17-7", "16-0", "16-1", "O", "X", "X", "X", "X", "X", "X", "X"],
      ["X", "O", "O", "O", "O", "O", "X", "O", "A1", "17-4", "17-5", "16-2", "16-3", "O", "X", "O", "O", "O", "O", "O", "X"],
      ["X", "O", "X", "X", "X", "O", "X", "O", "A2", "17-2", "17-3", "16-4", "16-5", "O", "X", "O", "X", "X", "X", "O", "X"],
      ["X", "O", "X", "X", "X", "O", "X", "O", "A3", "17-0", "17-1", "16-6", "16-7", "O", "X", "O", "X", "X", "X", "O", "X"],
      ["X", "O", "X", "X", "X", "O", "X", "O", "A4", "18-6", "18-7", "15-0", "15-1", "O", "X", "O", "X", "X", "X", "O", "X"],
      ["X", "O", "O", "O", "O", "O", "X", "O", "A5", "18-4", "18-5", "15-2", "15-3", "O", "X", "O", "O", "O", "O", "O", "X"],
      ["X", "X", "X", "X", "X", "X", "X", "O", "X", "O", "X", "O", "X", "O", "X", "X", "X", "X", "X", "X", "X"],
      ["O", "O", "O", "O", "O", "O", "O", "O", "A6", "18-2", "18-3", "15-4", "15-5", "O", "O", "O", "O", "O", "O", "O", "O"],
      ["A14", "A13", "A12", "A11", "A10", "A9", "X", "A8", "A7", "18-0", "18-1", "15-6", "15-7", "A7", "A6", "A5", "A4", "A3", "A2", "A1", "A0"],
      ["25-6", "25-7", "24-0", "24-1", "23-6", "23-7", "O", "22-0", "22-1", "19-6", "19-7", "14-0", "14-1", "9-6", "9-7", "8-0", "8-1", "3-6", "3-7", "2-0", "2-1"],
      ["25-4", "25-5", "24-2", "24-3", "23-4", "23-5", "X", "22-2", "22-3", "19-4", "19-5", "14-2", "14-3", "9-4", "9-5", "8-2", "8-3", "3-4", "3-5", "2-2", "2-3"],
      ["25-2", "25-3", "24-4", "24-5", "23-2", "23-3", "O", "22-4", "22-5", "19-2", "19-3", "14-4", "14-5", "9-2", "9-3", "8-4", "8-5", "3-2", "3-3", "2-4", "2-5"],
      ["25-0", "25-1", "24-6", "24-7", "23-0", "23-1", "X", "22-6", "22-7", "19-0", "19-1", "14-6", "14-7", "9-0", "9-1", "8-6", "8-7", "3-0", "3-1", "2-6", "2-7"],
      ["O", "O", "O", "O", "O", "O", "O", "O", "X", "20-6", "20-7", "13-0", "13-1", "10-6", "10-7", "7-0", "7-1", "4-6", "4-7", "1-0", "1-1"],
      ["X", "X", "X", "X", "X", "X", "X", "O", "A8", "20-4", "20-5", "13-2", "13-3", "10-4", "10-5", "7-2", "7-3", "4-4", "4-5", "1-2", "1-3"],
      ["X", "O", "O", "O", "O", "O", "X", "O", "A9", "20-2", "20-3", "13-4", "13-5", "10-2", "10-3", "7-4", "7-5", "4-2", "4-3", "1-4", "1-5"],
      ["X", "O", "X", "X", "X", "O", "X", "O", "A10", "20-0", "20-1", "13-6", "13-7", "10-0", "10-1", "7-6", "7-7", "4-0", "4-1", "1-6", "1-7"],
      ["X", "O", "X", "X", "X", "O", "X", "O", "A11", "21-6", "21-7", "12-0", "12-1", "11-6", "11-7", "6-0", "6-1", "5-6", "5-7", "0-0", "0-1"],
      ["X", "O", "X", "X", "X", "O", "X", "O", "A12", "21-4", "21-5", "12-2", "12-3", "11-4", "11-5", "6-2", "6-3", "5-4", "5-5", "0-2", "0-3"],
      ["X", "O", "O", "O", "O", "O", "X", "O", "A13", "21-2", "21-3", "12-4", "12-5", "11-2", "11-3", "6-4", "6-5", "5-2", "5-3", "0-4", "0-5"],
      ["X", "X", "X", "X", "X", "X", "X", "O", "A14", "21-0", "21-1", "12-6", "12-7", "11-0", "11-1", "6-6", "6-7", "5-0", "5-1", "0-6", "0-7"]
    ]

    // 存储坐标数据的数组
    const BLACK_POS = [];
    const WHITE_POS = [];
    const FORMAT_POS = [];
    const ENCODING_POS = [];
    const isMake = ref(false)
    //const QR_ERR_LEVEL_L = {name: 'L', bits: '01', c: 26, k: 19, e: 7};
    //const QR_ERR_LEVEL_H = { name: 'H', bits: '10', c: 26, k: 9, e: 17 };
    //let QR_ERR_LEVEL = QR_ERR_LEVEL_H; // 预设为 H 级别
    const errLevel = [
      { name: 'L', bits: '01', c: 26, k: 19, e: 7 },
      { name: 'M', bits: '00', c: 26, k: 17, e: 9 },
      { name: 'Q', bits: '11', c: 26, k: 13, e: 13 },
      { name: 'H', bits: '10', c: 26, k: 9, e: 17 }
    ]
    const QRCODE = ref([])

    const step1 = () => {
      QRCODE.value = Array(21).fill().map(() => Array(21).fill(-1));
      tableData1.value = QRCODE.value
      isCreate.value = true
    }
    const step2 = () => {
      if (isCreate.value) {
        for (let i = 0; i < 21; i++) {
          for (let j = 0; j < 21; j++) {
            if (BLACK_POS.some(pos => pos[0] === i && pos[1] === j)) {
              QRCODE.value[i][j] = 1;
            } else if (WHITE_POS.some(pos => pos[0] === i && pos[1] === j)) {
              QRCODE.value[i][j] = 0;
            }
          }
        }
        tableData1.value = QRCODE.value

      } else {
        alert("请先创建矩阵")
      }

    }
    const step3 = () => {
      if (isCreate.value) {
        const ERR_LEVEL = errLevel[selectedLevel.value].bits;
        const MASK_PATTEN = selectedCover.value; // 模式图案为：(i+j)%2==0
        let bit_string = ERR_LEVEL + MASK_PATTEN;
        bit_string = BCH(bit_string); // 生成 15 比特 BCH 码
        bit_string = bit_string.split('').reverse().join(''); // 反转码字
        FORMAT_POS.forEach(([index, rn, cn]) => {
          QRCODE.value[rn][cn] = parseInt(bit_string[index], 10);
        });
        tableData1.value = QRCODE.value

      } else {
        alert("请先创建矩阵")
      }

    }
    const step4 = () => {
      if (isCreate.value) {
        try {
          const numeric_text = qrInfo.value; // 字符数据

          let data_bit_string = NUMERIC_ENCODE(numeric_text); // 数字模式编码

          data_bit_string = data_bit_string.map(item => item.split('').reverse().join('')); // 转化成大端序
          console.log("data_bit_string", data_bit_string);
          ENCODING_POS.forEach(([cw, index, rn, cn]) => {
            QRCODE.value[rn][cn] = parseInt(data_bit_string[cw][index], 10);
          });

          tableData1.value = QRCODE.value
        } catch (e) {
          alert(e)
        }



      } else {
        alert("请先创建矩阵")
      }

    }
    const step5 = () => {
      if (isCreate.value) {
        const numeric_text = qrInfo.value; // 字符数据
        let data_bit_string = NUMERIC_ENCODE(numeric_text); // 数字模式编码
        data_bit_string = data_bit_string.map(item => item.split('').reverse().join('')); // 转化成大端序
        ENCODING_POS.forEach(([cw, index, rn, cn]) => {
          QRCODE.value[rn][cn] = parseInt(data_bit_string[cw][index] ^ QR_MASK_LEVEL[selectedCover.value](rn, cn), 10); // 填充并掩膜
        });
        tableData1.value = QRCODE.value
        console.log(QRCODE.value);

      } else {
        alert("请先创建矩阵")
      }

    }

    const conflateCode = () => {
      if (isDraw.value) {
        isMake.value = true
      } else {
        alert("请先绘制图形")

      }
    }
    const downloadQRCode = () => {
      if (isDraw.value && isMake.value) {
        const tableElement = qrTable.value; // 获取 table 元素
        html2canvas(tableElement, { scale: 2, }).then((canvas) => {
          // 将 canvas 转换为图片数据 URL
          const dataURL = canvas.toDataURL('image/png');

          // 创建下载链接并模拟点击
          const link = document.createElement('a');
          link.href = dataURL;
          link.download = 'qrcode.png';
          link.click();
        });
      } else {
        alert("请先合成二维码")

      }

    }
    const handleUploadClick = () => {
      const fileInput = document.querySelector('input[type="file"]');
      if (fileInput) {
        fileInput.click();
      }
    };
    const handleFileChange = (event) => {
      const file = event.target.files[0];
      if (file) {
        // 使用 FileReader 读取文件
        const reader = new FileReader();
        reader.onload = () => {
          // 将图片加载到一个 Image 对象
          const img = new Image();
          img.onload = () => {
            // 将图片画到 Canvas 上
            const canvas = document.createElement('canvas');
            const ctx = canvas.getContext('2d');
            canvas.width = img.width;
            canvas.height = img.height;
            ctx.drawImage(img, 0, 0, img.width, img.height);

            // 获取 Canvas 上的数据
            const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);

            // 使用 jsQR 解码二维码
            const code = jsQR(imageData.data, canvas.width, canvas.height);
            if (code) {
              identifyInfo.value = code.data; // 将识别到的二维码数据存储在 qrCodeData 中
            } else {
              identifyInfo.value = '没有识别到二维码';
            }
          };
          img.src = reader.result;
        };
        reader.readAsDataURL(file); // 将文件读取为 dataURL
      }
    };

    const generateGrid = () => {
      var num = Number(selectedVersion.value) * 4 + 17
      const newTableData = [];
      for (let i = 0; i < num; i++) {
        const row = [];
        for (let j = 0; j < num; j++) {
          row.push({ color: 'white', highlight: false });
        }
        newTableData.push(row);
      }
      tableData.value = newTableData;
      isMake.value = false
      isDraw.value = true
      // var testInfo = [
      //   [
      //     1,
      //     1,
      //     1,
      //     1,
      //     1,
      //     1,
      //     1,
      //     0,
      //     0,
      //     0,
      //     1,
      //     0,
      //     1,
      //     0,
      //     1,
      //     1,
      //     1,
      //     1,
      //     1,
      //     1,
      //     1
      //   ],
      //   [
      //     1,
      //     0,
      //     0,
      //     0,
      //     0,
      //     0,
      //     1,
      //     0,
      //     0,
      //     0,
      //     0,
      //     0,
      //     1,
      //     0,
      //     1,
      //     0,
      //     0,
      //     0,
      //     0,
      //     0,
      //     1
      //   ],
      //   [
      //     1,
      //     0,
      //     1,
      //     1,
      //     1,
      //     0,
      //     1,
      //     0,
      //     1,
      //     0,
      //     1,
      //     0,
      //     0,
      //     0,
      //     1,
      //     0,
      //     1,
      //     1,
      //     1,
      //     0,
      //     1
      //   ],
      //   [
      //     1,
      //     0,
      //     1,
      //     1,
      //     1,
      //     0,
      //     1,
      //     0,
      //     0,
      //     0,
      //     0,
      //     0,
      //     1,
      //     0,
      //     1,
      //     0,
      //     1,
      //     1,
      //     1,
      //     0,
      //     1
      //   ],
      //   [
      //     1,
      //     0,
      //     1,
      //     1,
      //     1,
      //     0,
      //     1,
      //     0,
      //     0,
      //     1,
      //     0,
      //     1,
      //     1,
      //     0,
      //     1,
      //     0,
      //     1,
      //     1,
      //     1,
      //     0,
      //     1
      //   ],
      //   [
      //     1,
      //     0,
      //     0,
      //     0,
      //     0,
      //     0,
      //     1,
      //     0,
      //     0,
      //     1,
      //     1,
      //     1,
      //     0,
      //     0,
      //     1,
      //     0,
      //     0,
      //     0,
      //     0,
      //     0,
      //     1
      //   ],
      //   [
      //     1,
      //     1,
      //     1,
      //     1,
      //     1,
      //     1,
      //     1,
      //     0,
      //     1,
      //     0,
      //     1,
      //     0,
      //     1,
      //     0,
      //     1,
      //     1,
      //     1,
      //     1,
      //     1,
      //     1,
      //     1
      //   ],
      //   [
      //     0,
      //     0,
      //     0,
      //     0,
      //     0,
      //     0,
      //     0,
      //     0,
      //     1,
      //     0,
      //     1,
      //     0,
      //     0,
      //     0,
      //     0,
      //     0,
      //     0,
      //     0,
      //     0,
      //     0,
      //     0
      //   ],
      //   [
      //     1,
      //     1,
      //     1,
      //     0,
      //     1,
      //     1,
      //     1,
      //     1,
      //     1,
      //     0,
      //     1,
      //     0,
      //     1,
      //     1,
      //     1,
      //     0,
      //     0,
      //     0,
      //     1,
      //     0,
      //     0
      //   ],
      //   [
      //     1,
      //     1,
      //     1,
      //     1,
      //     0,
      //     1,
      //     0,
      //     0,
      //     1,
      //     0,
      //     0,
      //     1,
      //     0,
      //     1,
      //     0,
      //     1,
      //     0,
      //     0,
      //     0,
      //     1,
      //     1
      //   ],
      //   [
      //     1,
      //     1,
      //     0,
      //     1,
      //     1,
      //     1,
      //     1,
      //     1,
      //     1,
      //     0,
      //     1,
      //     1,
      //     0,
      //     1,
      //     1,
      //     1,
      //     0,
      //     1,
      //     0,
      //     0,
      //     0
      //   ],
      //   [
      //     0,
      //     1,
      //     0,
      //     0,
      //     0,
      //     1,
      //     0,
      //     1,
      //     0,
      //     1,
      //     1,
      //     1,
      //     1,
      //     1,
      //     0,
      //     1,
      //     1,
      //     0,
      //     1,
      //     1,
      //     0
      //   ],
      //   [
      //     1,
      //     0,
      //     0,
      //     0,
      //     0,
      //     0,
      //     1,
      //     0,
      //     0,
      //     0,
      //     1,
      //     1,
      //     0,
      //     1,
      //     1,
      //     1,
      //     0,
      //     1,
      //     1,
      //     1,
      //     0
      //   ],
      //   [
      //     0,
      //     0,
      //     0,
      //     0,
      //     0,
      //     0,
      //     0,
      //     0,
      //     1,
      //     1,
      //     0,
      //     0,
      //     0,
      //     0,
      //     1,
      //     0,
      //     0,
      //     0,
      //     0,
      //     1,
      //     0
      //   ],
      //   [
      //     1,
      //     1,
      //     1,
      //     1,
      //     1,
      //     1,
      //     1,
      //     0,
      //     1,
      //     0,
      //     1,
      //     0,
      //     1,
      //     0,
      //     0,
      //     0,
      //     1,
      //     0,
      //     1,
      //     0,
      //     1
      //   ],
      //   [
      //     1,
      //     0,
      //     0,
      //     0,
      //     0,
      //     0,
      //     1,
      //     0,
      //     1,
      //     1,
      //     1,
      //     0,
      //     0,
      //     0,
      //     1,
      //     0,
      //     0,
      //     1,
      //     0,
      //     1,
      //     1
      //   ],
      //   [
      //     1,
      //     0,
      //     1,
      //     1,
      //     1,
      //     0,
      //     1,
      //     0,
      //     1,
      //     1,
      //     1,
      //     0,
      //     1,
      //     0,
      //     1,
      //     0,
      //     1,
      //     0,
      //     1,
      //     0,
      //     1
      //   ],
      //   [
      //     1,
      //     0,
      //     1,
      //     1,
      //     1,
      //     0,
      //     1,
      //     0,
      //     0,
      //     0,
      //     0,
      //     1,
      //     0,
      //     1,
      //     0,
      //     1,
      //     0,
      //     1,
      //     1,
      //     1,
      //     0
      //   ],
      //   [
      //     1,
      //     0,
      //     1,
      //     1,
      //     1,
      //     0,
      //     1,
      //     0,
      //     1,
      //     0,
      //     1,
      //     1,
      //     0,
      //     1,
      //     1,
      //     1,
      //     0,
      //     0,
      //     1,
      //     0,
      //     1
      //   ],
      //   [
      //     1,
      //     0,
      //     0,
      //     0,
      //     0,
      //     0,
      //     1,
      //     0,
      //     1,
      //     1,
      //     0,
      //     1,
      //     1,
      //     1,
      //     0,
      //     1,
      //     1,
      //     1,
      //     0,
      //     0,
      //     0
      //   ],
      //   [
      //     1,
      //     1,
      //     1,
      //     1,
      //     1,
      //     1,
      //     1,
      //     0,
      //     1,
      //     1,
      //     1,
      //     1,
      //     0,
      //     1,
      //     1,
      //     1,
      //     0,
      //     0,
      //     1,
      //     0,
      //     1
      //   ]
      // ]
      // const newTableData = [];
      // for (let i = 0; i < testInfo.length; i++) {
      //   const row = testInfo[i];
      //   var rowItem = []
      //   for (let j = 0; j < row.length; j++) {
      //     rowItem.push({ color: row[j] === 1 ? 'black' : 'white', highlight: false });
      //   }
      //   newTableData.push(rowItem);
      // }
      // console.log(newTableData);

      // tableData.value = newTableData;

    };
    // 鼠标悬停时高亮单元格
    const highlightCell = (rowIndex, colIndex) => {
      tableData.value[rowIndex][colIndex].highlight = true;
    };

    // 鼠标移开时移除高亮效果
    const removeHighlight = (rowIndex, colIndex) => {
      tableData.value[rowIndex][colIndex].highlight = false;
    };

    // 点击单元格切换颜色
    const toggleCellColor = (rowIndex, colIndex) => {
      const cell = tableData.value[rowIndex][colIndex];
      cell.color = cell.color === 'white' ? 'black' : 'white';
    };

    // QR Code 掩膜图案
    const QR_MASK_LEVEL = {
      '000': (i, j) => (i + j) % 2 === 0,
      '001': (i) => i % 2 == 0,
      '010': (j) => j % 3 == 0,
      '011': (i, j) => (i + j) % 3 == 0,
      '100': (i, j) => ((Math.trunc(i / 2) + Math.trunc(j / 3)) % 2) == 0,
      '101': (i, j) => ((i * j) % 2) + ((i * j) % 3) == 0,
      '110': (i, j) => (((i * j) % 2) + ((i * j) % 3)) % 2 == 0,
      '111': (i, j) => (((i * j) % 3) + ((i + j) % 2)) % 2 == 0,
    };

    // 多项式系数，用于生成纠错码字
    const QR_ERR_POLY = {
      7: [0, 87, 229, 146, 149, 238, 102, 21],
      9: [0, 87, 229, 146, 149, 238, 102, 21, 99, 5],
      13: [0, 43, 139, 206, 78, 43, 239, 123, 206, 214, 147, 24, 99, 150],
      17: [0, 43, 139, 206, 78, 43, 239, 123, 206, 214, 147, 24, 99, 150, 39, 243, 163, 136]
    };

    // 二元域多项式膜乘
    function gf2_poly_mul(a, b, ir_poly) {
      let ans = 0;
      const digit_1 = Math.floor(Math.log2(ir_poly));
      while (b) {
        if (b & 1) ans ^= a;
        a <<= 1;
        b >>= 1;
        if (a >> digit_1) {
          a ^= ir_poly;
        }
      }
      return ans;
    }

    // 二元域多项式膜幂
    function gf2_poly_pow(a, e, m) {
      let x = a;
      let t = 1;
      for (let i = 0; i < e; i++) {
        t = gf2_poly_mul(t, x, m);
      }
      return t;
    }

    // 二元域多项式带余除法
    function gf2_poly_divmod(a, b) {
      if (b === 0) throw new Error("Division by zero");
      let ans = 0;
      let digit_a = Math.floor(Math.log2(a));
      let digit_b = Math.floor(Math.log2(b));
      while (digit_a >= digit_b) {
        const rec = digit_a - digit_b;
        a ^= b << rec;
        ans |= 1 << rec;
        digit_a = Math.floor(Math.log2(a));
      }
      return [ans, a];
    }

    // GF(2^8) 多项式带余除法
    function poly_div(poly) {
      const qr_poly = 0b100011101; // 系数对应有限域的不可约多项式
      let a = poly.map(item => parseInt(item, 2)); // 01比特字符串转化为整数

      const p = QR_ERR_POLY[errLevel[selectedLevel.value].e].map(item => gf2_poly_pow(0b10, item, qr_poly));
      while (a.length >= p.length) {
        const n = a[0];
        for (let i = 0; i < p.length; i++) {
          a[i] ^= gf2_poly_mul(n, p[i], qr_poly);
        }
        a = a.slice(1);
      }
      return a.map(item => item.toString(2).padStart(8, '0')); // 整数系数转化为01比特字符串
    }

    // BCH码生成
    function BCH(bit_str) {
      const qr_gx = 0b10100110111; // x^10 + x^8 + x^5 + x^4 + x^2 + x + 1
      const xor_mask = 0b101010000010010; // 15 比特掩膜
      let n = parseInt(bit_str + '0'.repeat(10), 2);
      const [, r] = gf2_poly_divmod(n, qr_gx);
      const result = n ^ r ^ xor_mask;
      return result.toString(2).padStart(15, '0');
    }

    // 数字模式编码
    function NUMERIC_ENCODE(bit_str) {
      const NUMERIC_INDICATOR = '0001', TERMINATOR = '0000';
      const PAD1 = '11101100', PAD2 = '00010001';
      const length = bit_str.length;
      let result = '';

      // 数字字符编码
      while (bit_str) {
        let item = bit_str.slice(0, 3);
        if (item.length === 3) {
          const num = parseInt(item);
          if (isNaN(num)) throw new Error(`Invalid binary input: ${item}`);
          result += num.toString(2).padStart(10, '0');
        } else if (item.length === 2) {
          const num = parseInt(item);
          if (isNaN(num)) throw new Error(`Invalid binary input: ${item}`);
          result += num.toString(2).padStart(7, '0');
        } else if (item.length === 1) {
          const num = parseInt(item);
          if (isNaN(num)) throw new Error(`Invalid binary input: ${item}`);
          result += num.toString(2).padStart(4, '0');
        }
        bit_str = bit_str.slice(3);
      }
      result = NUMERIC_INDICATOR + (length).toString(2).padStart(10, '0') + result + TERMINATOR;

      // 填充至码字边界
      if (result.length % 8 !== 0) result += '0'.repeat(8 - result.length % 8);

      // 交替填充码字
      // eslint-disable-next-line no-constant-condition
      while (true) {
        //console.log("result.length / 8", result, result.length / 8);
        if (result.length / 8 !== errLevel[selectedLevel.value].k) result += PAD1;
        else break;
        if (result.length / 8 !== errLevel[selectedLevel.value].k) result += PAD2;
        else break;
      }

      // 拆分成8比特码字
      let resultArr = [];
      for (let i = 0; i < errLevel[selectedLevel.value].k; i++) {
        //console.log(result.slice(8 * i, 8 * i + 8));

        resultArr.push(result.slice(8 * i, 8 * i + 8));
      }
      // 拼接纠错码
      resultArr = resultArr.concat(poly_div(resultArr.concat(new Array(errLevel[selectedLevel.value].e).fill('00000000'))));
      return resultArr;
    }


    onMounted(() => {
      // 遍历二维数据，提取坐标信息
      for (let row = 0; row < 21; row++) {
        for (let col = 0; col < 21; col++) {
          let item = info[row][col];  // 获取当前格子内容

          if (item === 'X') {
            BLACK_POS.push([row, col]);  // 黑块坐标
          } else if (item === 'O') {
            WHITE_POS.push([row, col]);  // 白块坐标
          } else if (item[0] === 'A') {
            // 例如 "A1", "A2" 格式块
            FORMAT_POS.push([parseInt(item.substring(1)), row, col]);
          } else if (item.includes('-')) {
            // 例如 "1-0", "2-1" 编码块
            const [block, index] = item.split('-').map(Number);
            ENCODING_POS.push([block, index, row, col]);
          } else {
            // 处理无法识别的情况
            throw new Error(`Unknown data format: ${item}`);
          }
        }

      }

    });
    return {
      selectedLevel,
      selectedVersion,
      numbers,
      tableData,
      tableData1,
      valueList,
      qrInfo,
      info,
      selectedCover,
      qrTable,
      identifyInfo,
      isMake,
      conflateCode,
      handleUploadClick,
      generateGrid,
      highlightCell,
      removeHighlight,
      toggleCellColor,
      step1,
      step2,
      step3,
      step4,
      step5,
      downloadQRCode,
      handleFileChange
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
table {
  margin-top: 10px;
  border-collapse: collapse;
}

/* 表格单元格样式 */
td {
  width: 20px;
  height: 20px;
  border: 1px solid #dadada;
}

.highlight {
  outline: 2px solid orange;
}

#divCanvas {
  border-radius: 5px;
  width: 100%;
  height: 100%;
  /* float: left; */
}

.img {
  width: 25px;
  height: 25px;
  margin: 0 5px;
}

.container_set {
  padding: 5px 20px;
}

.title {
  margin-bottom: 10px;
  text-align: left;
}

.lcontainer {
  padding: 10px;
  text-align: left;
}

.container {
  display: flex;
  align-items: center;
  justify-content: center;
}


.card1 {
  width: 90%;
  height: 100%;
  margin-top: 10px;
  background: green;
  box-shadow: 0 8px 12px rgba(49, 49, 49, 0.3);
  border-radius: 5px;
  padding: 20px 20px 0 20px;
  background-color: white;
  transition: box-shadow 0.3s ease;
}

.grid {
  display: inline-grid;
  grid-template-columns: repeat(auto-fit, minmax(20px, 1fr));
  gap: 1px;
  margin-top: 20px;
}

::-webkit-scrollbar-thumb {
  background-color: #8d8c8c9d
}
</style>
